home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint104s.zoo
/
mint.src
/
bios.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-08
|
22KB
|
951 lines
/*
Copyright 1990,1991,1992 Eric R. Smith.
Copyright 1992,1993 Atari Corporation.
All rights reserved.
*/
/*
* BIOS replacement routines
*/
#include "mint.h"
#include "xbra.h"
#define UNDEF 0 /* should match definition in tty.c */
/* some key definitions */
#define CTRLALT 0xc
#define DEL 0x53 /* scan code of delete key */
#define UNDO 0x61 /* scan code of undo key */
/* BIOS device definitions */
#define CONSDEV 2
#define AUXDEV 1
/* BIOS devices 0..MAX_BHANDLE-1 can be redirected to GEMDOS files */
#define MAX_BHANDLE 4
/* BIOS redirection maps */
const short binput[MAX_BHANDLE] = { -3, -2, -1, -4 };
const short boutput[MAX_BHANDLE] = { -3, -2, -1, -5 };
/* tty structures for the BIOS devices -- see biosfs.c */
extern struct tty con_tty, aux_tty, midi_tty;
extern int tosvers; /* from main.c */
char *kbshft; /* set in main.c */
/* some BIOS vectors; note that the routines at these vectors may do nasty
* things to registers!
*/
#define RWABS *((long *)0x476L)
#define MEDIACH *((long *)0x47eL)
#define GETBPB *((long *)0x472L)
#define is_falcon ((mch & 0xffff0000L) == 0x00030000L)
#if 1
/* these are supposed to be tables holding the addresses of the
* first 8 BconXXX functions, but in fact only the first 5 are
* placed here (and device 5 only has Bconout implemented;
* we don't use that device (raw console) anyway).
*/
#define xconstat ((long *)0x51eL)
#define xconin ((long *)0x53eL)
#define xcostat ((long *)0x55eL)
#define xconout ((long *)0x57eL)
#define BCOSTAT(dev) \
((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
(int)callout1(xcostat[dev], dev) : Bcostat(dev))
#define BCONOUT(dev, c) \
((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
callout2(xconout[dev], dev, c) : Bconout(dev, c))
#define BCONSTAT(dev) \
((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
(int)callout1(xconstat[dev], dev) : Bconstat(dev))
#define BCONIN(dev) \
((tosvers >= 0x0102 && (unsigned)dev <= 4) ? \
callout1(xconin[dev], dev) : Bconin(dev))
#else
#define BCOSTAT(dev) Bcostat(dev)
#define BCONOUT(dev,c) Bconout(dev,c)
#define BCONSTAT(dev) Bconstat(dev)
#define BCONIN(dev) Bconin(dev)
#endif
/* variables for monitoring the keyboard */
IOREC_T *keyrec; /* keyboard i/o record pointer */
short kintr = 0; /* keyboard interrupt pending (see intr.s) */
/* Getmpb is not allowed under MiNT */
long ARGS_ON_STACK
getmpb(ptr)
void *ptr;
{
UNUSED(ptr);
DEBUG(("failed call to Getmpb"));
return -1;
}
/*
* Note that BIOS handles 0 - MAX_BHANDLE now reference file handles;
* to get the physical devices, go through u:\dev\
*
* A note on translation: all of the bco[n]XXX functions have a "u"
* variant that is actually what the user calls. For example,
* ubconstat is the function that gets control after the user does
* a Bconstat. It figures out what device or file handle is
* appropriate. Typically, it will be a biosfs file handle; a
* request is sent to biosfs, and biosfs in turn figures out
* the "real" device and calls bconstat.
*/
/*
* WARNING: syscall.spp assumes that ubconstat never blocks.
*/
long ARGS_ON_STACK
ubconstat(dev)
int dev;
{
if (dev < MAX_BHANDLE) {
FILEPTR *f = curproc->handle[binput[dev]];
return file_instat(f) ? -1 : 0;
}
else
return bconstat(dev);
}
long
bconstat(dev)
int dev;
{
if (dev == CONSDEV) {
if (checkkeys()) return 0;
return (keyrec->head != keyrec->tail) ? -1 : 0;
}
if (dev == AUXDEV && has_bconmap)
dev = curproc->bconmap;
/* compensate for a bug in the Falcon BIOS */
if (dev == 7 && is_falcon)
return Bconstat(1);
return BCONSTAT(dev);
}
/* bconin: input a character */
/*
* WARNING: syscall.spp assumes that ubconin never
* blocks if ubconstat returns non-zero.
*/
long ARGS_ON_STACK
ubconin(dev)
int dev;
{
if (dev < MAX_BHANDLE) {
FILEPTR *f = curproc->handle[binput[dev]];
return file_getchar(f, RAW);
}
else
return bconin(dev);
}
long
bconin(dev)
int dev;
{
IOREC_T *k;
long r;
short h;
if (dev == CONSDEV) {
k = keyrec;
again:
while (k->tail == k->head) {
yield();
}
if (checkkeys()) goto again;
h = k->head + 4;
if (h >= k->buflen)
h = 0;
r = *((long *)(k->bufaddr + h));
k->head = h;
return r;
}
else {
if (dev == AUXDEV && has_bconmap)
dev = curproc->bconmap;
if (dev == 7 && is_falcon) {
while (!Bconstat(1))
yield();
return Bconin(1);
}
if (dev > 0) {
while (!BCONSTAT(dev)) {
yield();
}
}
}
r = BCONIN(dev);
return r;
}
/* bconout: output a character.
* returns 0 for failure, nonzero for success
*/
long ARGS_ON_STACK
ubconout(dev, c)
int dev, c;
{
FILEPTR *f;
char outp;
if (dev < MAX_BHANDLE) {
f = curproc->handle[boutput[dev]];
if (!f) return 0;
if (is_terminal(f)) {
return tty_putchar(f, ((long)c)&0x00ff, RAW);
}
outp = c;
return (*f->dev->write)(f, &outp, 1L);
}
else if (dev == 5) {
c &= 0x00ff;
f = curproc->handle[-1];
if (!f) return 0;
if (is_terminal(f)) {
if (c < ' ') {
/* MW hack for quoted characters */
tty_putchar(f, (long)'\033', RAW);
tty_putchar(f, (long)'Q', RAW);
}
return tty_putchar(f, ((long)c)&0x00ff, RAW);
}
/* note: we're assuming sizeof(int) == 2 here! */
outp = c;
return (*f->dev->write)(f, &outp, 1L);
} else
return bconout(dev, c);
}
long
bconout(dev, c)
int dev,c;
{
int statdev;
long endtime;
#define curtime *((unsigned long *)0x4baL)
if (dev == AUXDEV && has_bconmap) {
dev = curproc->bconmap;
}
/* compensate for a known BIOS bug; MIDI and IKBD are switched */
if (dev == 3) { /* MIDI */
statdev = 4;
} else if (dev == 4) {
statdev = 3;
} else if (dev == 7 && is_falcon) {
/* Falcon BIOS bug */
(void)Bconout(1,c);
return 1;
} else {
statdev = dev;
}
/* provide a 10 second time out */
if (!BCOSTAT(statdev)) {
endtime = curtime + 10*200L;
do {
#if 0
yield();
#endif
} while (!BCOSTAT(statdev) && curtime < endtime);
if ( curtime >= endtime) return 0;
}
/* special case: many text accelerators return a bad value from
* Bconout, so we ignore the returned value for the console
*/
if (dev != CONSDEV) {
/* NOTE: if your compiler complains about the next line, then Bconout is
* improperly declared in your osbind.h header file. it should be returning
* a long value; some libraries incorrectly have Bconout returning void
* (or cast the returned value to void)
*/
return BCONOUT(dev,c);
} else {
(void)BCONOUT(dev, c);
return 1;
}
}
/* rwabs: various disk stuff */
/* BUG: Rwabs should respect Dlock */
long ARGS_ON_STACK
rwabs(rwflag, buffer, number, recno, dev, lrecno)
int rwflag, number, recno, dev;
void *buffer;
long lrecno;
{
long r;
extern PROC *dlockproc[]; /* in dosdir.c */
if (dev >= 0 && dev < NUM_DRIVES && dlockproc[dev]) {
if (dlockproc[dev] != curproc) {
DEBUG(("Rwabs: device %c is locked", dev+'A'));
return ELOCKED;
}
}
/* Note that some (most?) Rwabs device drivers don't bother saving
* registers, whereas our compiler expects politeness. So we go
* via callout(), which will save registers for us.
*/
r = callout(RWABS, rwflag, buffer, number, recno, dev, lrecno);
return r;
}
/* setexc: set exception vector */
long ARGS_ON_STACK
setexc(number, vector)
int number;
long vector;
{
long *place;
long old;
extern long save_dos, save_bios, save_xbios; /* in main.c */
extern int no_mem_prot; /* in main.c */
place = (long *)(((long)number) << 2);
if (number == 0x21) /* trap_1 */
old = save_dos;
else if (number == 0x2d) /* trap_13 */
old = save_bios;
else if (number == 0x2e) /* trap_14 */
old = save_xbios;
else if (number == 0x101)
old = (long)curproc->criticerr; /* critical error vector */
else if (number == 0x102)
old = curproc->ctxt[SYSCALL].term_vec; /* GEMDOS term vector */
else
old = *place;
if (vector > 0) {
/* validate vector; this will cau